package P128_DeadLock;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author xufy
 * @version 1.0
 * @description 预防死锁
 **/
public class DeadLock {

    //线程都有启动、运行、销毁过程，一个线程不能重复使用
    public static void main(String[] args) throws InterruptedException {
       Foo foo=new Foo();
//       new Thread(foo).start();

        //死锁
       final A a=new A();
       final B b=new B();
       new Thread(new Runnable() {
           @Override
           public void run() {
               a.a1(b);
           }
       },"线程A").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                b.b1(a);
            }
        },"线程B").start();
    }

}
class A{
    public synchronized  void a1(B b){
        String name=Thread.currentThread().getName();
        System.out.println(name+" 进入A.a1()");
        try{
            Thread.sleep(1000);
        }catch(Exception e){

        }
        System.out.println(name+" 试图访问B.b2()");
        b.b2();
    }
    public synchronized void a2(){
        System.out.println("进入 A.a2()");
    }
}
class B{
    private final Lock lock=new ReentrantLock();

    public synchronized  void b1(A a){
        String name=Thread.currentThread().getName();
        System.out.println(name+" 进入B.b1()");
        try{
            Thread.sleep(1000);
        }catch(Exception e){

        }
        System.out.println(name+" 试图访问A.a2()");
        a.a2();
    }
    public synchronized void b2(){
        System.out.println("进入 B.b2()");
    }
    public void b21(){
        try{
            //2s后仍无法或多资源，则释放锁
            if(lock.tryLock(2,TimeUnit.SECONDS)){
                System.out.println("进入B.b2()");
            }
        }catch (InterruptedException e){
        }finally {
            lock.unlock();
        }

    }
}


class Foo implements Runnable{

    @Override
    public void run() {
        fun(10);
    }
    //实际作用与 foo对象上，线程持有对象可多次重入fun方法
    public synchronized void fun(int i){
        if(--i >0){
            for (int j = 0; j < i; j++) {
                System.out.println("*");
            }
            System.out.println(i);
            fun(i);
        }
    }
}